#ifndef __FOC_CALI_H__
#define __FOC_CALI_H__

#include "app_main.h"
#include "motor_foc.h"
#include "motor_enco.h"
#include "motor_drive.h"

//=================================用户修改======================================
// 控制周期，非常重要！！！一般是ADC注入捕获和PWM运行频率的倒数，因为控制算法一般都放在那
#define MotorCtrlTerm 0.00005f
//===================================END========================================

typedef struct
{
    // 相电阻
    float Rs;
    // 相电感
    float Ls;
    // 磁链
    float flux;
    // 极对数
    uint8_t pairs;
    // 转动惯量
    float Jx;
    // 阻尼因子
    float delta;
    // 负载转矩
    float Tl;
    // 电磁转矩
    float Te;
    // 转矩常数
    float Kt;
    // 反电动势系数
    float Ke;
    // 线圈温度
    float Tcoil;
} stMotor_Para_type;

typedef enum
{
    // 电机停止
    __Motor_Stop,
    // 电机初始化
    __Motor_Start,
    // 电机等待
    __Motor_Wait,
    // 电机运行
    __Motor_Run,
    // 电机预启动
    __Motor_Precharge,
} emMotor_State_type;

typedef enum
{
    dragvf_mode = 0, // VF强拖
    dragif_mode = 1, // IF强拖

    volt_mode = 2,    // 电压开环
    spd_volt = 3,     // 速度-电压
    pos_volt = 4,     // 位置-电压
    pos_spd_volt = 5, // 位置-速度-电压

    curr_mode = 6,    // 电流闭环
    spd_curr = 7,     // 速度-电流
    pos_curr = 8,     // 位置-电流
    pos_spd_curr = 9, // 位置-速度-电流

    mag_enc_cali = 10, // 磁编码器校准模式
    hall_cali = 11,    // 霍尔校准模式

    iden_para = 12, // 电机参数辨识

    mode_num,
} emMotorCtrl_Mode_type;

typedef enum
{
    // 编码器未找到：检查编码器线是否正确连接
    __Enco_Not_Found,
    // 编码器弱磁警告：检查磁铁是否正确安装
    __Enco_No_Mag,
    // 奇偶校验多次失败：检查编码器线附近是否有强干扰
    __Enco_Parity_Fault,
} emMotorCtrl_Error_type;

typedef struct
{
    // 电机物理参数
    stMotor_Para_type mtPara;
    // 电机实时状态
    emMotor_State_type mtState;
    // 编码器参数
    stMotorEnco_Para_type mePara;
    // FOC算法参数
    stFOC_Para_type focPara;
    // 电机控制模式
    emMotorCtrl_Mode_type Mode;
    // 电机控制遇到的错误
    emMotorCtrl_Error_type Error;
} stMotorCtrl_type;

extern stMotorCtrl_type MC;

void Motor_Ctrl_initSystem(void);
void Motor_Ctrl_runState(void);
void Motor_Ctrl_runMode(void);
void Motor_Ctrl_process(void);
void Motor_Ctrl_errorHandler(emMotorCtrl_Error_type _Error);

#endif